home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Snippets / PNL Libraries / MyLists.p < prev    next >
Encoding:
Text File  |  1996-05-29  |  10.2 KB  |  415 lines  |  [TEXT/CWIE]

  1. unit MyLists;
  2.  
  3. interface
  4.  
  5.     uses
  6.         Types;
  7.         
  8. { Some types have been changed to avoid clashing with the list manager }
  9.     type
  10.         listHead = ^listNode;            { Was listHeadHandle }
  11.         listItem = ^listNode;            { Was listHandle }
  12.         listNode = record
  13.                 head: boolean;
  14.                 next: listItem;
  15.                 prev: listItem;
  16.                 this: Handle;
  17.             end;
  18.  
  19.     var
  20.         listError: boolean;
  21.  
  22.     procedure CreateList (var l: listHead);
  23.     procedure DestroyList (var l: listHead; dispose: boolean);
  24.  
  25.     procedure ReturnHead (lh: listHead; var l: listItem);
  26.     (* <a> b c / <a> b c / <a> b c / <a> / <a> / <> *)
  27.     procedure ReturnTail (lh: listHead; var l: listItem);
  28.     (* a b c <> / a b c <> / a b c <> / a b c <> / a <> / a <> / <> *)
  29.  
  30.     procedure MoveToHead (var l: listItem);
  31.     (* <a> b c / <a> b c / <a> b c / <a> b c / <a> / <a> / <> *)
  32.     procedure MoveToTail (var l: listItem);
  33.     (* a b c <> / a b c <> / a b c <> / a b c <> / a <> / a <> / <> *)
  34.     procedure MoveToNext (var l: listItem);
  35.     (* a <b> c / a b <c> / a b c <> / error / a <> / error / error *)
  36.     procedure MoveToPrev (var l: listItem);
  37.     (* error / <a> b c / a <b> c / a b <c> / error / <a> / error *)
  38.  
  39.     function FindItem (lh: listHead; it: univ Handle; var l: listItem): boolean;
  40.  
  41.     procedure AddHead (l: listHead; it: univ Handle);
  42.     (* x <a> b c / x a <b> c / x a b <c> / x a b c <> / x <a> / x a <> / x <>*)
  43.     procedure AddTail (l: listHead; it: univ Handle);
  44.     (* <a> b c x / a <b> c x / a b <c> x / a b c x <> / <a> x / a x <> / x <>*)
  45.     procedure AddBefore (l: listItem; it: univ Handle);
  46.     (* x <a> b c / a x <b> c / a b x <c> / a b c x <> / x <a> / a x <> / x <>*)
  47.     procedure AddAfter (l: listItem; it: univ Handle);
  48.     (* <a> x b c / a <b> x c / a b <c> x / error / <a> x / error / error *)
  49.  
  50.     procedure DeleteHead (l: listHead; var it: univ Handle);
  51.     (* <?> b c / <b> c / b <c> / b c <> / <?> / <> / error *)
  52.     procedure DeleteTail (l: listHead; var it: univ Handle);
  53.     (* <a> b / a <b> / a b <?> / a b <> / <?> / <> / error *)
  54.     procedure DeletePrev (l: listItem; var it: univ Handle);
  55.     (* error / <b> c / a <c> / a b <> / error / <> / error *)
  56.     procedure DeleteNext (l: listItem; var it: univ Handle);
  57.     (* <a> c / a <b> / error / error / error / error / error *)
  58.     procedure DeleteItem (var l: listItem; var it: univ Handle);
  59.     (* <b> c / a <c> / a b <> / error / <> / error / error *)
  60.  
  61.     procedure FetchHead (l: listHead; var it: univ Handle);
  62.     (* a / a / a / a / a / a / error  *)
  63.     procedure FetchTail (l: listHead; var it: univ Handle);
  64.     (* c / c / c / c / a / a / error  *)
  65.     procedure FetchNext (l: listItem; var it: univ Handle);
  66.     (* b / c / error / error / error / error / error *)
  67.     procedure FetchPrev (l: listItem; var it: univ Handle);
  68.     (* error / a / b / c / error / a / error *)
  69.     procedure Fetch (l: listItem; var it: univ Handle);
  70.     (* a / b / c / error / a / error / error *)
  71.  
  72.     function IsHead (l: listItem): boolean;
  73.     (* T / F / F / F / T / F / T *)
  74.     function IsTail (l: listItem): boolean;
  75.     (* F / F / F / T / F / T / T *)
  76.     function IsEmpty (l: listHead): boolean;
  77.     (* F / F / F / F / F / F / T *)
  78.  
  79.     procedure DisplayList (lh: listHead);
  80.    (* To the Text Screen *)
  81.     procedure ValidateList (lh: listHead; maxlen: longint);
  82.     (* Check the list for validity, maxlen is the maximum valid length *)
  83.  
  84. implementation
  85.  
  86.     uses
  87.         Memory;
  88. { Internal Routines }
  89.  
  90.     procedure DestroyListPtr (var l: univ listItem);
  91.     begin
  92. {    l^^.next := nil;                These dont do any good }
  93. {    l ^ ^ . prev := nil;            cause DisposHandle }
  94. {    l  ^ ^ . this := nil;            destroys the data }
  95.         DisposePtr(Ptr(l));
  96.         l := nil;
  97.     end;
  98.  
  99.     procedure CreateListPtr (var l: univ listItem);
  100.     begin
  101.         l := listItem(NewPtr(SizeOf(listNode)));
  102.         if l = nil then begin
  103.             listError := true;
  104.             DebugStr('CreateListPtr Failed!');
  105.         end;
  106.     end;
  107.  
  108.     procedure MoveToStart (var l: univ listItem);
  109.         var
  110.             tmp: listItem;
  111.     begin
  112.         if not l^.head then begin
  113.             tmp := l;
  114.             repeat
  115.                 l := l^.next;
  116.             until (tmp = l) or l^.head;
  117.             if tmp = l then begin
  118.                 listError := true;
  119.             end;
  120.         end;
  121.     end;
  122.  
  123.     procedure InsertBefore (l: univ listItem; var it: univ Handle);
  124.         var
  125.             tmp: listItem;
  126.     begin
  127.         CreateListPtr(tmp);
  128.         if tmp <> nil then begin
  129.             tmp^.head := false;
  130.             tmp^.this := it;
  131.             tmp^.next := l;
  132.             tmp^.prev := l^.prev;
  133.             l^.prev^.next := tmp;
  134.             l^.prev := tmp;
  135.         end;
  136.     end;
  137.  
  138.     procedure DeleteNode (l: listItem; var it: univ Handle);
  139.     begin
  140.         if l^.head then begin
  141.             listError := true;
  142.         end else begin
  143.             it := l^.this;
  144.             l^.prev^.next := l^.next;
  145.             l^.next^.prev := l^.prev;
  146.             DestroyListPtr(l);
  147.         end;
  148.     end;
  149.  
  150.     procedure FetchNode (l: listItem; var it: univ Handle);
  151.     begin
  152.         if l^.head then begin
  153.             listError := true;
  154.         end;
  155.         it := l^.this;
  156.     end;
  157.  
  158. { External Routines }
  159.  
  160.     procedure CreateList (var l: listHead);
  161.     begin
  162.         CreateListPtr(l);
  163.         if l <> nil then begin
  164.             l^.head := true;
  165.             l^.next := listItem(l);
  166.             l^.prev := listItem(l);
  167.             l^.this := nil;
  168.         end;
  169.     end;
  170.  
  171.     procedure DestroyList (var l: listHead; dispose: boolean);
  172.         var
  173.             tmp, tmp2: listItem;
  174.     begin
  175.         tmp := l^.next;
  176.         while tmp <> listItem(l) do begin
  177.             tmp2 := tmp;
  178.             tmp := tmp^.next;
  179.             if dispose then begin
  180.                 DisposeHandle(tmp2^.this);
  181.             end;
  182.             DestroyListPtr(tmp2);
  183.         end;
  184.         if dispose then begin
  185.             DisposeHandle(l^.this);
  186.         end;
  187.         DestroyListPtr(l);
  188.     end;
  189.  
  190.     procedure ReturnHead (lh: listHead; var l: listItem);
  191.     (* <a> b c / <a> b c / <a> b c / <a> / <a> / <> *)
  192.     begin
  193.         l := lh^.next;
  194.     end;
  195.  
  196.     procedure ReturnTail (lh: listHead; var l: listItem);
  197.     (* a b c <> / a b c <> / a b c <> / a b c <> / a <> / a <> / <> *)
  198.     begin
  199.         l := listItem(lh);
  200.     end;
  201.  
  202.     function FindItem (lh: listHead; it: univ Handle; var l: listItem): boolean;
  203.     begin
  204.         l := listItem(lh)^.next;
  205.         while (not l^.head) and (it <> l^.this) do begin
  206.             l := l^.next;
  207.         end;
  208.         FindItem := (not l^.head) and (it = l^.this);
  209.     end;
  210.  
  211.     procedure MoveToHead (var l: listItem);
  212.     (* <a> b c / <a> b c / <a> b c / <a> b c / <a> / <a> / <> *)
  213.     begin
  214.         MoveToStart(l);
  215.         l := l^.next;
  216.     end;
  217.  
  218.     procedure MoveToTail (var l: listItem);
  219.     (* a b c <> / a b c <> / a b c <> / a b c <> / a <> / a <> / <> *)
  220.     begin
  221.         MoveToStart(l);
  222.     end;
  223.  
  224.     procedure MoveToNext (var l: listItem);
  225.     (* a <b> c / a b <c> / a b c <> / error / a <> / error / error *)
  226.     begin
  227.         if l^.head then begin
  228.             listError := true;
  229.         end else begin
  230.             l := l^.next;
  231.         end;
  232.     end;
  233.  
  234.     procedure MoveToPrev (var l: listItem);
  235.     (* error / <a> b c / a <b> c / a b <c> / error / <a> / error *)
  236.     begin
  237.         if l^.prev^.head then begin
  238.             listError := true;
  239.         end else begin
  240.             l := l^.prev;
  241.         end;
  242.     end;
  243.  
  244.     procedure AddHead (l: listHead; it: univ Handle);
  245.     (* x <a> b c / x a <b> c / x a b <c> / x a b c <> / x <a> / x a <> / x <>*)
  246.     begin
  247.         InsertBefore(l^.next, it);
  248.     end;
  249.  
  250.     procedure AddTail (l: listHead; it: univ Handle);
  251.     (* <a> b c x / a <b> c x / a b <c> x / a b c x <> / <a> x / a x <> / x <>*)
  252.     begin
  253.         InsertBefore(l, it);
  254.     end;
  255.  
  256.     procedure AddBefore (l: listItem; it: univ Handle);
  257.     (* x <a> b c / a x <b> c / a b x <c> / a b c x <> / x <a> / a x <> / x <>*)
  258.     begin
  259.         InsertBefore(l, it);
  260.     end;
  261.  
  262.     procedure AddAfter (l: listItem; it: univ Handle);
  263.     (* <a> x b c / a <b> x c / a b <c> x / error / <a> x / error / error *)
  264.     begin
  265.         if l^.head then begin
  266.             listError := true;
  267.         end else begin
  268.             InsertBefore(l^.next, it);
  269.         end;
  270.     end;
  271.  
  272.     procedure DeleteHead (l: listHead; var it: univ Handle);
  273.     (* <?> b c / <b> c / b <c> / b c <> / <?> / <> / error *)
  274.     begin
  275.         DeleteNode(l^.next, it);
  276.     end;
  277.  
  278.     procedure DeleteTail (l: listHead; var it: univ Handle);
  279.     (* <a> b / a <b> / a b <?> / a b <> / <?> / <> / error *)
  280.     begin
  281.         DeleteNode(l^.prev, it);
  282.     end;
  283.  
  284.     procedure DeletePrev (l: listItem; var it: univ Handle);
  285.     (* error / <b> c / a <c> / a b <> / error / <> / error *)
  286.     begin
  287.         DeleteNode(l^.prev, it);
  288.     end;
  289.  
  290.     procedure DeleteNext (l: listItem; var it: univ Handle);
  291.     (* <a> c / a <b> / error / error / error / error / error *)
  292.     begin
  293.         if l^.head then begin
  294.             listError := true;
  295.             it := nil;
  296.         end
  297.         else
  298.             DeleteNode(l^.next, it);
  299.     end;
  300.  
  301.     procedure DeleteItem (var l: listItem; var it: univ Handle);
  302.     (* <b> c / a <c> / a b <> / error / <> / error / error *)
  303.         var
  304.             tmp: listItem;
  305.     begin
  306.         if l^.head then begin
  307.             listError := true;
  308.             it := nil;
  309.         end else begin
  310.             tmp := l^.next;
  311.             DeleteNode(l, it);
  312.             l := tmp;
  313.         end;
  314.     end;
  315.  
  316.     procedure FetchHead (l: listHead; var it: univ Handle);
  317.     (* a / a / a / a / a / a / error  *)
  318.     begin
  319.         FetchNode(l^.next, it);
  320.     end;
  321.  
  322.     procedure FetchTail (l: listHead; var it: univ Handle);
  323.     (* c / c / c / c / a / a / error  *)
  324.     begin
  325.         FetchNode(l^.prev, it);
  326.     end;
  327.  
  328.     procedure FetchNext (l: listItem; var it: univ Handle);
  329.     (* b / c / error / error / error / error / error *)
  330.     begin
  331.         if l^.head then begin
  332.             listError := true;
  333.             it := nil;
  334.         end
  335.         else
  336.             FetchNode(l^.next, it);
  337.     end;
  338.  
  339.     procedure FetchPrev (l: listItem; var it: univ Handle);
  340.     (* error / a / b / c / error / a / error *)
  341.     begin
  342.         FetchNode(l^.prev, it);
  343.     end;
  344.  
  345.     procedure Fetch (l: listItem; var it: univ Handle);
  346.     (* a / b / c / error / a / error / error *)
  347.     begin
  348.         FetchNode(l, it);
  349.     end;
  350.  
  351.     function IsHead (l: listItem): boolean;
  352.     (* T / F / F / F / T / F / T *)
  353.     begin
  354.         IsHead := l^.prev^.head;
  355.     end;
  356.  
  357.     function IsTail (l: listItem): boolean;
  358.     (* F / F / F / T / F / T / T *)
  359.     begin
  360.         IsTail := l^.head;
  361.     end;
  362.  
  363.     function IsEmpty (l: listHead): boolean;
  364.     (* F / F / F / F / F / F / T *)
  365.     begin
  366.         IsEmpty := l^.next = listItem(l);
  367.     end;
  368.  
  369.     procedure DisplayList (lh: listHead);
  370.         var
  371.             l: listItem;
  372.             hhhh: Handle;
  373.     begin
  374.         ReturnHead(lh, l);
  375.         write('(');
  376.         while not IsTail(l) do begin
  377.             Fetch(l, hhhh);
  378.             MoveToNext(l);
  379.             write(hhhh);
  380.             if not IsTail(l) then begin
  381.                 write(',');
  382.             end;
  383.         end;
  384.         writeln('  )');
  385.     end;
  386.  
  387.     procedure ValidateList (lh: listHead; maxlen: longint);
  388.         var
  389.             item: listItem;
  390.             count: integer;
  391.             data: Handle;
  392.     begin
  393.         if lh = nil then begin
  394.             DebugStr('ValidateList: lh = nil');
  395.         end;
  396.         count := 0;
  397.         ReturnHead(lh, item);
  398.         if item = nil then begin
  399.             DebugStr('ValidateList: first item = nil');
  400.         end;
  401.         while not IsTail(item) do begin
  402.             Fetch(item, data);
  403.             MoveToNext(item);
  404.             if item = nil then begin
  405.                 DebugStr('ValidateList: list item = nil');
  406.             end;
  407.             count := count + 1;
  408.             if count > maxlen then begin
  409.                 DebugStr('ValidateList: List too long - probably bad');
  410.                 leave;
  411.             end;
  412.         end;
  413.     end;
  414.  
  415. end.